﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;

namespace EventScavenger
{
    public partial class Collectors : Form
    {
        public Collectors()
        {
            InitializeComponent();
        }

        private EventScavengerDAL eventScavengerDAL;
        string lvgPrefix = "Server: ";

        public DialogResult Show(EventScavengerDAL eventScavengerDAL)
        {
            this.eventScavengerDAL = eventScavengerDAL;
            return ShowDialog();
        }

        #region Form events
        private void Collectors_Load(object sender, EventArgs e)
        {
            restartInAdminModeToolStripMenuItem.Visible = !IsAdmin();
            backgroundWorkerLoading.RunWorkerAsync();
        } 
        #endregion

        #region Loading
        private void backgroundWorkerLoading_DoWork(object sender, DoWorkEventArgs e)
        {
            this.Invoke((MethodInvoker)delegate()
            {
                
                lvwCollectors.Items.Clear();
                lvwCollectors.Items.Add("Loading...");
                System.Threading.Thread.Sleep(250);

                List<Collector> collectors = eventScavengerDAL.GetCollectorList();
                GlobalSettingsData globalSettingsData = eventScavengerDAL.GetGlobalSettings();

                Application.DoEvents();
                lvwCollectors.Items.Clear();
                foreach (Collector collector in (from Collector  col in collectors
                                                 orderby col.ReaperName
                                                 select col))
                {
                    ListViewItem lvi = new ListViewItem(collector.Name);
                    lvi.ImageIndex = 0;
                    lvi.SubItems.Add(collector.ServiceName);

                    if (collector.Enabled)
                        lvi.ForeColor = SystemColors.WindowText;
                    else
                        lvi.ForeColor = Color.Gray;

                    lvi.Tag = collector;

                    ListViewGroup lvg = (from ListViewGroup g in lvwCollectors.Groups
                                         where g.Header == lvgPrefix + collector.ReaperName
                                         select g).FirstOrDefault();
                    if (lvg == null)
                    {
                        lvg = new ListViewGroup(lvgPrefix + collector.ReaperName);
                        lvg.Tag = collector.ReaperName;
                        lvwCollectors.Groups.Add(lvg);
                    }
                    lvi.Group = lvg;

                    if (globalSettingsData.MaintenanceRunner == collector.Name)
                        lvi.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75f, FontStyle.Bold);

                    lvwCollectors.Items.Add(lvi);
                }
                lvwCollectors_SelectedIndexChanged(null, null);
                timerCheckServiceState.Enabled = false;
                timerCheckServiceState.Enabled = true;
                
            });
        } 
        #endregion

        #region Toolbar events
        private void toolStripButtonNew_Click(object sender, EventArgs e)
        {
            try
            {
                CollectorEdit collectorEdit = new CollectorEdit();
                if (System.IO.File.Exists(@"C:\Program Files\Hen IT\Event Scavenger\Service 5.0\EventReaper.exe"))
                    collectorEdit.SelectedCollector.ServicePath = @"C:\Program Files\Hen IT\Event Scavenger\Service 5.0\EventReaper.exe";
                else if (System.IO.File.Exists(@"C:\Program Files (x86)\Hen IT\Event Scavenger\Service 5.0\EventReaper.exe"))
                    collectorEdit.SelectedCollector.ServicePath = @"C:\Program Files (x86)\Hen IT\Event Scavenger\Service 5.0\EventReaper.exe";
                if (collectorEdit.Show(eventScavengerDAL) == DialogResult.OK)
                {
                    eventScavengerDAL.InsertCollector(collectorEdit.SelectedCollector);
                    backgroundWorkerLoading.RunWorkerAsync();
                    //ListViewItem lvi = new ListViewItem(collectorEdit.SelectedCollector.Name);
                    //lvi.SubItems.Add(collectorEdit.SelectedCollector.ThreadRecycleFrequencyMinutes.ToString());
                    //lvi.SubItems.Add(collectorEdit.SelectedCollector.NextRecycleTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    //lvi.SubItems.Add(collectorEdit.SelectedCollector.ThreadRecyclingEnabled.ToString());
                    //lvi.Tag = collectorEdit.SelectedCollector;
                    //lvwCollectors.Items.Add(lvi);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Edit", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void toolStripButtonEdit_Click(object sender, EventArgs e)
        {
            if (lvwCollectors.SelectedItems.Count > 0)
            {
                try
                {
                    CollectorEdit collectorEdit = new CollectorEdit();
                    collectorEdit.SelectedCollector = (Collector)lvwCollectors.SelectedItems[0].Tag;
                    if (collectorEdit.Show(eventScavengerDAL) == DialogResult.OK)
                    {
                        eventScavengerDAL.UpdateCollector(collectorEdit.SelectedCollector);
                        lvwCollectors.SelectedItems[0].Tag = collectorEdit.SelectedCollector;
                        lvwCollectors.SelectedItems[0].Text = collectorEdit.SelectedCollector.Name;
                        lvwCollectors.SelectedItems[0].SubItems[1].Text = collectorEdit.SelectedCollector.ServiceName;
                        if (collectorEdit.SelectedCollector.Enabled)
                            lvwCollectors.SelectedItems[0].ForeColor = SystemColors.WindowText;
                        else
                            lvwCollectors.SelectedItems[0].ForeColor = Color.Gray;

                        ListViewGroup lvg = (from ListViewGroup g in lvwCollectors.Groups
                                             where g.Header == lvgPrefix + collectorEdit.SelectedCollector.ReaperName
                                             select g).FirstOrDefault();
                        if (lvg == null)
                        {
                            lvg = new ListViewGroup(lvgPrefix + collectorEdit.SelectedCollector.ReaperName);
                            lvwCollectors.Groups.Add(lvg);
                        }
                        lvwCollectors.SelectedItems[0].Group = lvg;

                        GlobalSettingsData globalSettingsData = eventScavengerDAL.GetGlobalSettings();
                        if (globalSettingsData.MaintenanceRunner == collectorEdit.SelectedCollector.Name)
                            backgroundWorkerLoading.RunWorkerAsync();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Edit", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        private void toolStripButtonRemove_Click(object sender, EventArgs e)
        {
            try
            {
                if (lvwCollectors.SelectedItems.Count > 0)
                {
                    if (MessageBox.Show("Are you sure you want to delete this collector(s)?\r\nIf there are any logs still linked with it the delete will fail", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
                        {
                            Collector collector = (Collector)lvi.Tag;
                            eventScavengerDAL.DeleteCollector(collector);
                        }
                    }
                    backgroundWorkerLoading.RunWorkerAsync();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        } 
        private void refrechToolStripButton_Click(object sender, EventArgs e)
        {
            backgroundWorkerLoading.RunWorkerAsync();
        }
        #endregion

        #region Listview events
        private void lvwCollectors_SelectedIndexChanged(object sender, EventArgs e)
        {
            toolStripButtonEdit.Enabled = lvwCollectors.SelectedItems.Count == 1;
            editToolStripMenuItem.Enabled = lvwCollectors.SelectedItems.Count == 1;
            toolStripButtonRemove.Enabled = (lvwCollectors.SelectedItems.Count > 0);
            deleteToolStripMenuItem.Enabled = (lvwCollectors.SelectedItems.Count > 0);

            startToolStripMenuItem.Enabled = false;
            stopToolStripMenuItem.Enabled = false;
            pauseToolStripMenuItem.Enabled = false;
            continueToolStripMenuItem.Enabled = false;
            bool isAdmin = IsAdmin();

            foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
            {
                if (lvi.Tag is Collector)
                {
                    Collector col = (Collector)lvi.Tag;
                    enabledToolStripMenuItem.Checked = col.Enabled;
                    if (col.Enabled && 
                        (!System.Net.Dns.GetHostName().ToLower().StartsWith(col.ReaperName.ToLower()) || isAdmin)
                        )
                    {
                        if (lvi.ImageIndex == 1)
                            startToolStripMenuItem.Enabled = true;
                        else if (lvi.ImageIndex == 3)
                        {
                            stopToolStripMenuItem.Enabled = true;
                            pauseToolStripMenuItem.Enabled = true;
                        }
                        else if (lvi.ImageIndex == 4)
                        {
                            continueToolStripMenuItem.Enabled = true;
                        }
                    }
                }
            }
        }
        private void lvwCollectors_Resize(object sender, EventArgs e)
        {
            columnHeaderCollector.Width = lvwCollectors.ClientSize.Width - lvwCollectors.Columns[1].Width;
        } 
        private void lvwCollectors_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                toolStripButtonEdit_Click(sender, e);
            }
        }
        #endregion

        #region Context menu events
        private void enabledToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
                {
                    if (lvi.Tag is Collector)
                    {
                        Collector col = (Collector)lvi.Tag;
                        col.Enabled = enabledToolStripMenuItem.Checked;
                        eventScavengerDAL.UpdateCollector(col);
                        if (col.Enabled)
                            lvi.ForeColor = SystemColors.WindowText;
                        else
                            lvi.ForeColor = Color.Gray;
                        lvi.Tag = col;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void restartInAdminModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.Save();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;
            startInfo.FileName = Application.ExecutablePath;
            //if (action.Length > 0)
            //    startInfo.Arguments = string.Format("{0} \"{1}\" {2}", action, serviceName, hostName);
            startInfo.Verb = "runas";
            try
            {
                System.Diagnostics.Process p = System.Diagnostics.Process.Start(startInfo);
            }
            catch (System.ComponentModel.Win32Exception) // ex)
            {
                return;
            }

            Application.Exit();
        }
        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
            {
                if (lvi.ImageIndex == 1)
                {
                    AttemptServiceStart(lvi);
                }
            }
        }
        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
            {
                if (lvi.ImageIndex == 3)
                {
                    AttemptServiceStop(lvi);
                }
            }
            timerCheckServiceState.Enabled = false;
            timerCheckServiceState.Enabled = true;
        }
        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
            {
                if (lvi.ImageIndex == 3)
                {
                    AttemptServicePause(lvi);
                }
            }
            timerCheckServiceState.Enabled = true;
        }
        private void continueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwCollectors.SelectedItems)
            {
                if (lvi.ImageIndex == 4)
                {
                    AttemptServiceContinue(lvi);
                }
            }
            timerCheckServiceState.Enabled = true;
        }
        #endregion

        #region Service management
        private int GetServiceState(ListViewItem lvi)
        {
            try
            {
                if (lvi.Tag is Collector)
                {
                    Collector col = (Collector)lvi.Tag;
                    if (col.Enabled)
                    {
                        ServiceController sc = new ServiceController(col.ServiceName, col.ReaperName);
                        if (sc.Status == ServiceControllerStatus.Running)
                            return 3;
                        else if (sc.Status == ServiceControllerStatus.Stopped)
                            return 1;
                        else if (sc.Status == ServiceControllerStatus.Paused)
                            return 4;
                        else
                            return 2;
                    }
                }
            }
            catch
            {
                return 0; //Unknown
            }
            return 0;
        }
        private void AttemptServiceStart(ListViewItem lvi)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                if (lvi.Tag is Collector)
                {
                    Collector rs = (Collector)lvi.Tag;
                    if (rs.Enabled)
                    {
                        ServiceController sc = new ServiceController(rs.ServiceName, rs.ReaperName);
                        if (sc.Status == ServiceControllerStatus.Stopped)
                        {
                            sc.Start();
                            sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30));
                            lvi.ImageIndex = 3;                            
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Stop", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            Cursor.Current = Cursors.Default;
        }
        private void AttemptServiceStop(ListViewItem lvi)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {                
                if (lvi.Tag is Collector)
                {
                    Collector rs = (Collector)lvi.Tag;
                    ServiceController sc = new ServiceController(rs.ServiceName, rs.ReaperName);
                    if (rs.Enabled)
                    {
                        if (sc.Status == ServiceControllerStatus.Running)
                        {
                            sc.Stop();
                            sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 30));
                            lvi.ImageIndex = 1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Stop", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            Cursor.Current = Cursors.Default;
        }
        private void AttemptServicePause(ListViewItem lvi)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                if (lvi.Tag is Collector)
                {
                    Collector rs = (Collector)lvi.Tag;
                    ServiceController sc = new ServiceController(rs.ServiceName, rs.ReaperName);
                    if (rs.Enabled)
                    {
                        if (sc.Status == ServiceControllerStatus.Running)
                        {
                            sc.Pause();
                            sc.WaitForStatus(ServiceControllerStatus.Paused, new TimeSpan(0, 0, 30));
                            lvi.ImageIndex = 4;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Stop", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            Cursor.Current = Cursors.Default;
        }
        private void AttemptServiceContinue(ListViewItem lvi)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                if (lvi.Tag is Collector)
                {
                    Collector rs = (Collector)lvi.Tag;
                    ServiceController sc = new ServiceController(rs.ServiceName, rs.ReaperName);
                    if (rs.Enabled)
                    {
                        if (sc.Status == ServiceControllerStatus.Paused)
                        {
                            sc.Continue();
                            sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30));
                            lvi.ImageIndex = 3;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Stop", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            Cursor.Current = Cursors.Default;
        }
        #endregion

        #region Service state
        private void timerCheckServiceState_Tick(object sender, EventArgs e)
        {
            timerCheckServiceState.Enabled = false;
            foreach (ListViewGroup lvg in lvwCollectors.Groups)
            {
                try
                {
                    if (PingHelper.CanPingHost(lvg.Tag.ToString()))
                    {

                        
                        foreach (ListViewItem lvi in lvg.Items)
                        {
                            try
                            {
                                lvi.ImageIndex = GetServiceState(lvi);
                            }
                            catch
                            {
                                lvi.ImageIndex = 0;
                            }
                        }
                    }
                }
                catch { }
            }
        } 
        #endregion

        #region Checking Admin mode
        bool IsAdmin()
        {
            string strIdentity;
            try
            {
                AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
                System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent();
                System.Security.Principal.WindowsPrincipal wp = new System.Security.Principal.WindowsPrincipal(wi);
                strIdentity = wp.Identity.Name;

                if (wp.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
                    return true;
                else
                    return false;
            }
            catch
            {
                return false;
            }

        } 
        #endregion


    }
}
